/*
 * power4-utils.h
 *
 */

#include <hpbcg-asm-common.h>

#define ADDINSN(VAL) (*(hpbcg_asm_pc++) = (VAL))
#define ORG(PTR) (hpbcg_asm_pc = (insn *) PTR)

typedef unsigned int insn;
static insn *hpbcg_asm_pc;

static void iflush(register insn *addr, register insn *last)
{
  (void) printf("Flush data cache from %p to %p\n", addr, last);  
}

#define sub_iRRR(RD,RA,RB)		subf_iRRR(RD,RB,RA)	
#define subi_iRRI(RD,RA,IM)		addi_iRRI(RD,RA,-(IM))
#define subis_iRRI(RD,RA,IM)		addis_iRRI(RD,RA,-(IM))
#define subic_iRRI(RD,RA,IM)		addic_iRRI(RD,RA,-(IM))

#define sub__iRRR(RD,RA,RB)		subf__iRRR(RD,RB,RA)
#define subc_iRRR(RD,RA,RB)		subfc_iRRR(RD,RB,RA)
#define sube_iRRR(RD,RA,RB)		subfe_iRRR(RD,RB,RA)
#define subo_iRRR(RD,RA,RB)		subfo_iRRR(RD,RB,RA)

#define cmpwi_iIRI(C,RA,IM)		cmpi_iIIRI(C,0,RA,IM)
#define cmpw_iIRR(C,RA,RB)		cmp_iIIRR(C,0,RA,RB)
#define cmplwi_iIRI(C,RA,IM)		cmpli_iIIRI(C,0,RA,IM)
#define cmplw_iIRR(C,RA,RB)		cmpl_iIIRR(C,0,RA,RB)

#define cmpwi_iRI(RA,IM)		cmpwi_iIRI(0,RA,IM)
#define cmpw_iRR(RA,RB)			cmpw_iIRR(0,RA,RB)
#define cmplwi_iRI(RA,IM)		cmplwi_iIRI(0,RA,IM)
#define cmplw_iRR(RA,RB)		cmplw_iIRR(0,RA,RB)

#define extlwi_iRRII(RA,RS,N,B)		rlwinm_iRRIII(RA, RS,            B,	0,     (N)-1)
#define extrwi_iRRII(RA,RS,N,B)		rlwinm_iRRIII(RA, RS,      (B)+(N),  32-(N),        31)
#define inslwi_iRRII(RA,RS,N,B)		rlwimi_iRRIII(RA, RS,       32-(B),	B, (B)+(N)-1)
#define insrwi_iRRII(RA,RS,N,B)		rlwimi_iRRIII(RA, RS, 32-((B)+(N)),	B, (B)+(N)-1)
#define rotlwi_iRRI(RA,RS,N)		rlwinm_iRRIII(RA, RS,            N,	0,        31)
#define rotrwi_iRRI(RA,RS,N)		rlwinm_iRRIII(RA, RS,       32-(N),	0,        31)
#define rotlw_iRRR(RA,RS,RB)		rlwnm_iRRRII( RA, RS,           RB,	0,        31)
#define slwi_iRRI(RA,RS,N)		rlwinm_iRRIII(RA, RS,            N,	0,    31-(N))
#define srwi_iRRI(RA,RS,N)		rlwinm_iRRIII(RA, RS,       32-(N),	N,        31)
#define clrlwi_iRRI(RA,RS,N)		rlwinm_iRRIII(RA, RS,            0,	N,        31)
#define clrrwi_iRRI(RA,RS,N)		rlwinm_iRRIII(RA, RS,            0,	0,    31-(N))
#define clrlslwi_iRRII(RA,RS,B,N)	rlwinm_iRRIII(RA, RS,            N, (B)-(N),    31-(N))

#define bt_iII(C,D)			bc_iRRI(12, C, D)
#define bf_iII(C,D)			bc_iRRI( 4, C, D)
#define bdnzt_iII(C,D)			bc_iRRI( 8, C, D)
#define bdnzf_iII(C,D)			bc_iRRI( 0, C, D)
#define bdnz_iI(D)			bc_iRRI(17, 0, D)
#define bdzt_iII(C,D)			bc_iRRI(10, C, D)
#define bdz_iI(D)			bc_iRRI(18, 0, D)
#define bdzf_iII(C,D)			bc_iRRI( 2, C, D)
		
#define bctr_i()			bcctr_iII(20, 0)
#define bctrl_i()			bcctrl_iII(20, 0)
		
#define blr_i()				bclr_iII(20, 0)		
#define blrl_i()			bclrl_iII(20, 0)
		

#define bltlr_iI(CR)			bclr_iII(12, ((CR)<<2)+0)	
#define blelr_iI(CR)			bclr_iII( 4, ((CR)<<2)+1)
#define beqlr_iI(CR)			bclr_iII(12, ((CR)<<2)+2)
#define bgelr_iI(CR)			bclr_iII( 4, ((CR)<<2)+0)
#define bgtlr_iI(CR)			bclr_iII(12, ((CR)<<2)+1)
#define bnllr_iI(CR)			bclr_iII( 4, ((CR)<<2)+0)
#define bnelr_iI(CR)			bclr_iII( 4, ((CR)<<2)+2)
#define bnglr_iI(CR)			bclr_iII( 4, ((CR)<<2)+1)
#define bsolr_iI(CR)			bclr_iII(12, ((CR)<<2)+3)
#define bnslr_iI(CR)			bclr_iII( 4, ((CR)<<2)+3)
#define bunlr_iI(CR)			bclr_iII(12, ((CR)<<2)+3)
#define bnulr_iI(CR)			bclr_iII( 4, ((CR)<<2)+3)
		
#define bltlrl_iI(CR)			bclrl_iII(12, ((CR)<<2)+0)
#define blelrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+1)
#define beqlrl_iI(CR)			bclrl_iII(12, ((CR)<<2)+2)
#define bgelrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+0)
#define bgtlrl_iI(CR)			bclrl_iII(12, ((CR)<<2)+1)
#define bnllrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+0)
#define bnelrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+2)
#define bnglrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+1)
#define bsolrl_iI(CR)			bclrl_iII(12, ((CR)<<2)+3)
#define bnslrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+3)
#define bunlrl_iI(CR)			bclrl_iII(12, ((CR)<<2)+3)
#define bnulrl_iI(CR)			bclrl_iII( 4, ((CR)<<2)+3)
		
#define bltctr_iI(CR)			bcctr_iII(12, ((CR)<<2)+0)
#define blectr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+1)
#define beqctr_iI(CR)			bcctr_iII(12, ((CR)<<2)+2)
#define bgectr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+0)
#define bgtctr_iI(CR)			bcctr_iII(12, ((CR)<<2)+1)
#define bnlctr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+0)
#define bnectr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+2)
#define bngctr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+1)
#define bsoctr_iI(CR)			bcctr_iII(12, ((CR)<<2)+3)
#define bnsctr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+3)
#define bunctr_iI(CR)			bcctr_iII(12, ((CR)<<2)+3)
#define bnuctr_iI(CR)			bcctr_iII( 4, ((CR)<<2)+3)
		
#define bltctrl_iI(CR)			bcctrl_iII(12, ((CR)<<2)+0)	
#define blectrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+1)
#define beqctrl_iI(CR)			bcctrl_iII(12, ((CR)<<2)+2)
#define bgectrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+0)
#define bgtctrl_iI(CR)			bcctrl_iII(12, ((CR)<<2)+1)
#define bnlctrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+0)
#define bnectrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+2)
#define bngctrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+1)
#define bsoctrl_iI(CR)			bcctrl_iII(12, ((CR)<<2)+3)
#define bnsctrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+3)
#define bunctrl_iI(CR)			bcctrl_iII(12, ((CR)<<2)+3)
#define bnuctrl_iI(CR)			bcctrl_iII( 4, ((CR)<<2)+3)
		

#define bltlr_i()			bltlr_iI(0)  
#define blelr_i()			blelr_iI(0)  
#define beqlr_i()			beqlr_iI(0)  
#define bgelr_i()			bgelr_iI(0)  
#define bgtlr_i()			bgtlr_iI(0)  
#define bnllr_i()			bnllr_iI(0)  
#define bnelr_i()			bnelr_iI(0)  
#define bnglr_i()			bnglr_iI(0)  
#define bsolr_i()			bsolr_iI(0)  
#define bnslr_i()			bnslr_iI(0)  
#define bunlr_i()			bunlr_iI(0)  
#define bnulr_i()			bnulr_iI(0)  
					            
#define bltlrl_i()			bltlrl_iI(0) 
#define blelrl_i()			blelrl_iI(0) 
#define beqlrl_i()			beqlrl_iI(0) 
#define bgelrl_i()			bgelrl_iI(0) 
#define bgtlrl_i()			bgtlrl_iI(0) 
#define bnllrl_i()			bnllrl_iI(0) 
#define bnelrl_i()			bnelrl_iI(0) 
#define bnglrl_i()			bnglrl_iI(0) 
#define bsolrl_i()			bsolrl_iI(0) 
#define bnslrl_i()			bnslrl_iI(0) 
#define bunlrl_i()			bunlrl_iI(0) 
#define bnulrl_i()			bnulrl_iI(0) 
					            
#define bltctr_i()			bltctr_iI(0) 
#define blectr_i()			blectr_iI(0) 
#define beqctr_i()			beqctr_iI(0) 
#define bgectr_i()			bgectr_iI(0) 
#define bgtctr_i()			bgtctr_iI(0) 
#define bnlctr_i()			bnlctr_iI(0) 
#define bnectr_i()			bnectr_iI(0) 
#define bngctr_i()			bngctr_iI(0) 
#define bsoctr_i()			bsoctr_iI(0) 
#define bnsctr_i()			bnsctr_iI(0) 
#define bunctr_i()			bunctr_iI(0) 
#define bnuctr_i()			bnuctr_iI(0) 
					            
#define bltctrl_i()			bltctrl_iI(0)
#define blectrl_i()			blectrl_iI(0)
#define beqctrl_i()			beqctrl_iI(0)
#define bgectrl_i()			bgectrl_iI(0)
#define bgtctrl_i()			bgtctrl_iI(0)
#define bnlctrl_i()			bnlctrl_iI(0)
#define bnectrl_i()			bnectrl_iI(0)
#define bngctrl_i()			bngctrl_iI(0)
#define bsoctrl_i()			bsoctrl_iI(0)
#define bnsctrl_i()			bnsctrl_iI(0)
#define bunctrl_i()			bunctrl_iI(0)
#define bnuctrl_i()			bnuctrl_iI(0)


#define blt_iII(C,D)			bc_iRRI(12, ((C)<<2)+0, D)
#define ble_iII(C,D)			bc_iRRI( 4, ((C)<<2)+1, D)
#define beq_iII(C,D)			bc_iRRI(12, ((C)<<2)+2, D)
#define bge_iII(C,D)			bc_iRRI( 4, ((C)<<2)+0, D)
#define bgt_iII(C,D)			bc_iRRI(12, ((C)<<2)+1, D)
#define bnl_iII(C,D)			bc_iRRI( 4, ((C)<<2)+0, D)
#define bne_iII(C,D)			bc_iRRI( 4, ((C)<<2)+2, D)
#define bng_iII(C,D)			bc_iRRI( 4, ((C)<<2)+1, D)
#define bso_iII(C,D)			bc_iRRI(12, ((C)<<2)+3, D)
#define bns_iII(C,D)			bc_iRRI( 4, ((C)<<2)+3, D)
#define bun_iII(C,D)			bc_iRRI(12, ((C)<<2)+3, D)
#define bnu_iII(C,D)			bc_iRRI( 4, ((C)<<2)+3, D)

#define blt_iI(D)			blt_iII(0,D)
#define ble_iI(D)			ble_iII(0,D)
#define beq_iI(D)			beq_iII(0,D)
#define bge_iI(D)			bge_iII(0,D)
#define bgt_iI(D)			bgt_iII(0,D)
#define bnl_iI(D)			bnl_iII(0,D)
#define bne_iI(D)			bne_iII(0,D)
#define bng_iI(D)			bng_iII(0,D)
#define bso_iI(D)			bso_iII(0,D)
#define bns_iI(D)			bns_iII(0,D)
#define bun_iI(D)			bun_iII(0,D)
#define bnu_iI(D)			bnu_iII(0,D)

#define bltl_iII(C,D)			bcl_iIII(12, ((C)<<2)+0, D)
#define blel_iII(C,D)			bcl_iIII( 4, ((C)<<2)+1, D)
#define beql_iII(C,D)			bcl_iIII(12, ((C)<<2)+2, D)
#define bgel_iII(C,D)			bcl_iIII( 4, ((C)<<2)+0, D)
#define bgtl_iII(C,D)			bcl_iIII(12, ((C)<<2)+1, D)
#define bnll_iII(C,D)			bcl_iIII( 4, ((C)<<2)+0, D)
#define bnel_iII(C,D)			bcl_iIII( 4, ((C)<<2)+2, D)
#define bngl_iII(C,D)			bcl_iIII( 4, ((C)<<2)+1, D)
#define bsol_iII(C,D)			bcl_iIII(12, ((C)<<2)+3, D)
#define bnsl_iII(C,D)			bcl_iIII( 4, ((C)<<2)+3, D)
#define bunl_iII(C,D)			bcl_iIII(12, ((C)<<2)+3, D)
#define bnul_iII(C,D)			bcl_iIII( 4, ((C)<<2)+3, D)

#define bltl_iI(D)			bltl_iII(0,D)
#define blel_iI(D)			blel_iII(0,D)
#define beql_iI(D)			beql_iII(0,D)
#define bgel_iI(D)			bgel_iII(0,D)
#define bgtl_iI(D)			bgtl_iII(0,D)
#define bnll_iI(D)			bnll_iII(0,D)
#define bnel_iI(D)			bnel_iII(0,D)
#define bngl_iI(D)			bngl_iII(0,D)
#define bsol_iI(D)			bsol_iII(0,D)
#define bnsl_iI(D)			bnsl_iII(0,D)
#define bunl_iI(D)			bunl_iII(0,D)
#define bnul_iI(D)			bnul_iII(0,D)


#define crset_iI(BX)			creqv_iIII(BX, BX, BX)
#define crclr_iI(BX)			crxor_iIII(BX, BX, BX)
#define crmove_iII(BX,BY)		cror_iIII(BX, BY, BY)
#define crnot_iII(BX,BY)		crnor_iIII(BX, BY, BY)
		
#define mtlr_iR(RS)			mtspr_iIR((8 << 5), RS)	
#define mtctr_iR(RS)			mtspr_iIR((9 << 5), RS)
#define mtxer_iR(RS)			mtspr_iIR((1 << 5), RS)
#define mfxer_iR(RD)			mfspr_iRI(RD, 1)
#define mflr_iR(RD)			mfspr_iRI(RD, 8)
#define mfctr_iR(RD)			mfspr_iRI(RD, 9)
		
#define nop_i()				ori_iRRI(0, 0, 0)	
#define li_iRI(RD,IM)			addi_iRRI(RD, 0, IM)
#define lis_iRI(RD,IM)			addis_iRRI(RD, 0, IM)
#define la_iRIR(RD,D,RA)		addi_iRRI(RD, RA, D)
#define la_iRRR(RD,RB,RA)		add_iRRR(RD, RA, RB)
#define mr_iRR(RA,RS)			or_iRRR(RA, RS, RS)
#define not_iRR(RA,RS)			nor_iRRR(RA, RS, RS)


#define lbzu_iRX(RD,RA,RB)		lbzux_iRRR(RD,RA,RB)
#define lbz_iRX(RD,RA,RB)		lbzx_iRRR(RD,RA,RB)
#define lhau_iRX(RD,RA,RB)		lhaux_iRRR(RD,RA,RB)
#define lha_iRX(RD,RA,RB)		lhax_iRRR(RD,RA,RB)
#define lhbr_iRX(RD,RA,RB)		lhbrx_iRRR(RD,RA,RB)
#define lhzu_iRX(RD,RA,RB)		lhzux_iRRR(RD,RA,RB)
#define lhz_iRX(RD,RA,RB)		lhzx_iRRR(RD,RA,RB)
#define lwbr_iRX(RD,RA,RB)		lwbrx_iRRR(RD,RA,RB)
#define lwzu_iRX(RD, RA, RB)		lwzux_iRRR(RD, RA, RB)
#define lwz_iRX(RD, RA, RB)		lwzx_iRRR(RD, RA, RB)
#define stbu_iRX(RD,RA,RB)		stbux_iRRR(RD,RA,RB)
#define stb_iRX(RD,RA,RB)		stbx_iRRR(RD,RA,RB)
#define sthbr_iRX(RS,RA,RB)		sthbrx_iRRR(RS,RA,RB)
#define sthu_iRX(RS,RA,RB)		sthux_iRRR(RS,RA,RB)
#define sth_iRX(RS,RA,RB)		sthx_iRRR(RS,RA,RB)
#define stwbr_iRX(RS,RA,RB)		stwbrx_iRRR(RS,RA,RB)
#define stwc_iRX(RS,RA,RB)		stwcx_iRRR(RS,RA,RB)
#define stwcx__iRX(RS,RA,RB)		stwcx__iRRR(RS,RA,RB)

